package view

import (
	"github.com/gin-gonic/gin"
	"github.com/samber/lo"
	"github.com/sirupsen/logrus"
	"gopkg.in/guregu/null.v4"
	"monoblog/common"
	"monoblog/domain/auth"
	"monoblog/domain/dao"
	"monoblog/domain/dto"
	"monoblog/domain/model"
	"monoblog/domain/service"
	"net/http"
	"strings"
)

// Login 登录页面
func Login(ctx *gin.Context) {
	//获取登录用户
	loginUser, _ := ctx.Get("user")

	if loginUser != nil {
		logrus.Infof("已登录，无需重复登录，跳转到首页...")
		ctx.Redirect(http.StatusFound, "/index")
		return
	}
	ctx.HTML(http.StatusOK, "login.tmpl", gin.H{})
}

// Register 注册页面
func Register(ctx *gin.Context) {
	ctx.HTML(http.StatusOK, "register.tmpl", gin.H{})
}

// Index 首页页面
func Index(ctx *gin.Context) {
	//获取分类列表
	categories, err := service.GetCategoryService().FindList(ctx)
	if err != nil {
		logrus.Errorf("获取分类列表失败, err: %v", err)
		ctx.AbortWithStatus(http.StatusServiceUnavailable)
		return
	}
	//首页文章列表
	articles, err := service.GetArticleService().PopularBlogs(ctx, common.BaseQuery{Page: 1, Size: 20})
	if err != nil {
		logrus.Errorf("获取首页文章列表失败, err: %v", err)
		ctx.AbortWithStatus(http.StatusServiceUnavailable)
		return
	}

	//获取登录用户
	loginUser, _ := ctx.Get("user")

	ctx.HTML(http.StatusOK, "index.tmpl", gin.H{
		"categories": categories,
		"articles":   articles,

		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}

// Search 搜索页
func Search(ctx *gin.Context) {
	var query dto.SearchQuery

	if err := ctx.ShouldBind(&query); err != nil {
		logrus.Warnf("Query数据绑定失败, err: %v", err)
		ctx.AbortWithStatus(http.StatusBadRequest)
		return
	}

	//获取登录用户
	loginUser, _ := ctx.Get("user")

	query.Kw = strings.TrimSpace(query.Kw)
	//搜索关键词不能为空
	if query.Kw == "" {
		logrus.Infof("搜索关键词不能为空")
		ctx.HTML(http.StatusOK, "search.tmpl", gin.H{
			"keyword":  query.Kw,
			"articles": []*model.Article{},

			"loginUser":  loginUser,
			"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
		})
		return
	}

	//搜索结果：文章列表
	blogDocs, err := service.GetSearchService().SearchBlogs(ctx, query)
	if err != nil {
		logrus.Errorf("搜索文章列表失败, err: %v", err)
		ctx.AbortWithStatus(http.StatusServiceUnavailable)
		return
	}
	articles := lo.Map(blogDocs, dto.ConvertBlogDocToArticle)

	ctx.HTML(http.StatusOK, "search.tmpl", gin.H{
		"keyword":  query.Kw,
		"articles": articles,

		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}

// Category 分类页面
func Category(ctx *gin.Context) {
	cateId := ctx.Param("cateId")

	//获取分类列表
	categories, err := service.GetCategoryService().FindList(ctx)
	if err != nil || len(categories) == 0 {
		logrus.Errorf("分类列表不能无数据. 获取分类列表失败, err: %v", err)
		ctx.AbortWithStatus(http.StatusServiceUnavailable)
		return
	}

	if cateId == "" {
		cateId = categories[0].ID
	}

	//分类下的文章列表
	articles, err := service.GetArticleService().BlogsByCategory(ctx, cateId, common.BaseQuery{Page: 1, Size: 20})

	//获取登录用户
	loginUser, _ := ctx.Get("user")

	ctx.HTML(http.StatusOK, "category.tmpl", gin.H{
		"cateId":     cateId,
		"categories": categories,
		"articles":   articles,

		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}

// Section 专栏页面
func Section(ctx *gin.Context) {
	sectionId := ctx.Param("sectionId")

	section, err2 := service.GetSectionService().FindByID(ctx, sectionId)
	if err2 != nil {
		logrus.Errorf("根据专栏ID获取专栏详情失败, err: %v", err2)
		ctx.AbortWithStatus(http.StatusNotFound)
		return
	}

	//专栏下的文章列表
	articles, err := service.GetArticleService().BlogsBySection(ctx, sectionId, common.BaseQuery{Page: 1, Size: 20})
	if err != nil {
		logrus.Errorf("专栏下的文章列表获取失败, err: %v", err)
		ctx.AbortWithStatus(http.StatusServiceUnavailable)
		return
	}

	//获取登录用户
	loginUser, _ := ctx.Get("user")

	ctx.HTML(http.StatusOK, "section.tmpl", gin.H{
		"section":  section,
		"articles": articles,

		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}

// BlogDetail 文章详情页面
func BlogDetail(ctx *gin.Context) {
	id := ctx.Param("id")

	article, err := service.GetArticleService().ReadById(ctx, id, false)
	if err != nil {
		logrus.Errorf("根据文章ID获取文章详情失败, err: %v", err)
		ctx.AbortWithStatus(http.StatusServiceUnavailable)
		return
	}

	interestBlogs, err := service.GetArticleService().InterestedBlogs(ctx, "1")

	//获取登录用户
	loginUser, _ := ctx.Get("user")

	//预估阅读时间
	var estimateReadTime = 1 + len(article.Content)/1000

	ctx.HTML(http.StatusOK, "blog_detail.tmpl", gin.H{
		"title":         article.Title,
		"article":       article,
		"blogStats":     article.BlogStats,
		"readTime":      estimateReadTime,
		"interestBlogs": interestBlogs,

		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}

// BlogPreview 文章预览页面
func BlogPreview(ctx *gin.Context) {
	id := ctx.Param("id")

	article, err := service.GetArticleService().ReadById(ctx, id, true)
	if err != nil {
		logrus.Errorf("根据文章ID获取文章详情失败, err: %v", err)
		ctx.AbortWithStatus(http.StatusServiceUnavailable)
		return
	}

	interestBlogs, err := service.GetArticleService().InterestedBlogs(ctx, "1")

	//获取登录用户
	loginUser, _ := ctx.Get("user")

	//预估阅读时间
	var estimateReadTime = 1 + len(article.Content)/1000

	ctx.HTML(http.StatusOK, "blog_preview.tmpl", gin.H{
		"title":         article.Title + " - 预览",
		"article":       article,
		"blogStats":     article.BlogStats,
		"readTime":      estimateReadTime,
		"interestBlogs": interestBlogs,

		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}

func UserProfile(ctx *gin.Context) {
	userId := ctx.Param("userId")

	//用于判断是否是当前登录用户的主页
	_, isSelf := ctx.GetQuery("_current")

	//获取登录用户
	loginUser, _ := ctx.Get("user")

	// "我的页面", 登录用户才能访问
	if isSelf && loginUser == nil {
		logrus.Errorf("登录用户不能为空, 即将路由到/login ...")
		ctx.Redirect(http.StatusMovedPermanently, "/login")
		//ctx.AbortWithStatus(http.StatusUnauthorized)
		return
	}

	// "我的页面", 但是和登录用户不一致, 重定向到登录用户的主页
	if isSelf && loginUser != nil {
		if userId != loginUser.(*auth.LoginUser).UID {
			logrus.Errorf("非当前登录用户, 即将路由到/login ...")
			ctx.Redirect(http.StatusMovedPermanently, "/login")
			//ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
	}

	//查询用户信息
	user, err := service.GetUserService().FindByUserId(ctx, userId)
	if err != nil {
		logrus.Errorf("根据用户ID获取用户信息失败, err: %v", err)
		ctx.AbortWithStatus(http.StatusNotFound)
		return
	}
	//转换后的用户信息 userInfo
	userInfo := dto.ConvertWebUserToUserResp(user, 0)

	//已登录用户，访问Ta的主页，需要查询是不是已关注
	if loginUser != nil && !isSelf {
		stats, err1 := service.GetInterestService().StatsAtUser(ctx, userInfo.UID, loginUser.(*auth.LoginUser).UID)
		if err1 != nil {
			logrus.Errorf("根据用户ID查询关注状态失败, err: %v", err1.Error())
		} else {
			userInfo.IsFollow = null.BoolFrom(stats["followed"])
			userInfo.IsBlack = null.BoolFrom(stats["blacked"])
		}
	}

	interest, err := service.GetInterestService().GetInterest(ctx, userInfo.UID)
	favorites, err := service.GetInterestService().GetFavorites(ctx, userInfo.UID)

	statSummary := &dto.StatSummaryResp{
		FollowCount:   len(interest.FollowIds),
		FansCount:     len(interest.FansIds),
		FavoriteCount: len(favorites),
	}

	ctx.HTML(http.StatusOK, "user_profile.tmpl", gin.H{
		"title":       user.Nickname + "的主页",
		"userInfo":    userInfo,
		"isSelf":      isSelf,
		"statSummary": statSummary,

		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}

func Settings(ctx *gin.Context) {
	//获取登录用户
	loginUser, _ := ctx.Get("user")
	if loginUser == nil {
		logrus.Errorf("登录用户不能为空, 即将路由到/login ...")
		ctx.Redirect(http.StatusMovedPermanently, "/login")
		//ctx.AbortWithStatus(http.StatusUnauthorized)
		return
	}

	ctx.HTML(http.StatusOK, "settings.tmpl", gin.H{
		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}

// WritingBoard 创作中心页面
func WritingBoard(ctx *gin.Context) {
	//获取登录用户
	loginUser, _ := ctx.Get("user")
	if loginUser == nil {
		logrus.Errorf("登录用户不能为空, 即将路由到/login ...")
		ctx.Redirect(http.StatusMovedPermanently, "/login")
		//ctx.AbortWithStatus(http.StatusUnauthorized)
		return
	}
	var userId = loginUser.(*auth.LoginUser).UID

	//查询用户的专栏数量
	sectionCount, err := dao.NewSectionRepository().CountByUserId(userId)
	if err != nil {
		logrus.Errorf("根据用户ID查询专栏数量失败, err: %v", err)
		ctx.AbortWithStatus(http.StatusServiceUnavailable)
		return
	}

	counts, err := dao.NewArticleRepository().CountByUserId(userId)
	draftCount, _ := counts[model.DRAFT.String()]
	blogCount, _ := counts[model.PUBLISHED.String()]
	totalCount, _ := counts["total"]

	ctx.HTML(http.StatusOK, "writing_board.tmpl", gin.H{
		"sectionCount": sectionCount, //专栏数量
		"draftCount":   draftCount,   //草稿数量
		"blogCount":    blogCount,    //发布的文章数量
		"totalCount":   totalCount,   //文章总数量

		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}

// WritingEdit 创作中心-文章编辑页面
func WritingEdit(ctx *gin.Context) {
	id := ctx.Param("id")

	//获取登录用户
	loginUser, _ := ctx.Get("user")
	if loginUser == nil {
		logrus.Errorf("登录用户不能为空, 即将路由到/login ...")
		ctx.Redirect(http.StatusMovedPermanently, "/login")
		//ctx.AbortWithStatus(http.StatusUnauthorized)
		return
	}
	userId := loginUser.(*auth.LoginUser).UID //获取登录用户的ID

	//分类列表
	categories, err := service.GetCategoryService().FindList(ctx)
	if err != nil {
		logrus.Errorf("获取分类列表失败, err: %v", err)
		ctx.AbortWithStatus(http.StatusServiceUnavailable)
		return
	}

	sections, err := service.GetSectionService().SectionsByUserId(ctx, userId)
	if err != nil {
		logrus.Errorf("获取专栏列表失败, err: %v", err)
		ctx.AbortWithStatus(http.StatusServiceUnavailable)
		return
	}

	if id == "new" {
		ctx.HTML(http.StatusOK, "writing_edit.tmpl", gin.H{
			"title":      "",
			"categories": categories,
			"sections":   sections,
			"article":    model.Article{},

			"loginUser":  loginUser,
			"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
		})
		return
	}

	article, err := service.GetArticleService().FindByID(ctx, id)
	if err != nil {
		logrus.Errorf("根据文章ID获取文章详情失败, err: %v", err)
		ctx.AbortWithStatus(http.StatusNotFound)
		return
	}

	ctx.HTML(http.StatusOK, "writing_edit.tmpl", gin.H{
		"title":      article.Title,
		"categories": categories,
		"sections":   sections,

		"article": article,

		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}

// WritingManage 创作中心-文章管理页面
func WritingManage(ctx *gin.Context) {
	//获取登录用户
	loginUser, _ := ctx.Get("user")

	ctx.HTML(http.StatusOK, "writing_manage.tmpl", gin.H{
		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}

// WritingSection 创作中心-专栏管理页面
func WritingSection(ctx *gin.Context) {
	//获取登录用户
	loginUser, _ := ctx.Get("user")

	ctx.HTML(http.StatusOK, "writing_section.tmpl", gin.H{
		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}

// WritingAnalysis 创作中心-文章分析页面
func WritingAnalysis(ctx *gin.Context) {
	//获取登录用户
	loginUser, _ := ctx.Get("user")

	ctx.HTML(http.StatusOK, "writing_analysis.tmpl", gin.H{
		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}

// Feedback 意见反馈页面
func Feedback(ctx *gin.Context) {
	//获取登录用户
	loginUser, _ := ctx.Get("user")

	ctx.HTML(http.StatusOK, "feedback.tmpl", gin.H{
		"loginUser":  loginUser,
		"currentUrl": ctx.Request.RequestURI, //获取当前页面的完整URL
	})
}
